feat(installer): auto-inject BMAD badge into README#2361
feat(installer): auto-inject BMAD badge into README#2361terryso wants to merge 2 commits intobmad-code-org:mainfrom
Conversation
📝 WalkthroughWalkthroughThis pull request adds automated BMAD badge management to the installer. The install command gains a Changes
Sequence Diagram(s)sequenceDiagram
actor User
participant Install as install.js
participant Installer
participant Badge as badge.js
participant Git as Git Remote
participant README as README File
User->>Install: npm run install --no-badge
Install->>Installer: initialize(config with noBadge: true)
Note over Installer: ... installation proceeds ...
Installer->>Installer: finalize()
alt config.noBadge enabled
Installer->>Badge: resolveGitRemote(projectDir)
Badge->>Git: git config --get-regexp origin
Git-->>Badge: git remote URL
Badge-->>Installer: {owner, repo}
Installer->>Badge: findReadme(projectDir)
Badge-->>Installer: README file path
Installer->>README: read content
README-->>Installer: current content
Installer->>Badge: hasBadge(content)
Badge-->>Installer: boolean
alt Badge not already present
Installer->>Badge: injectBadge(content, owner, repo)
Badge-->>Installer: updated content with badge
Installer->>README: write updated content
README-->>Installer: success
else Badge already present
Installer-->>Installer: record "already present"
end
else config.noBadge disabled or missing
Installer-->>Installer: skip badge injection
end
Installer-->>User: installation complete
sequenceDiagram
actor User
participant Uninstall as uninstall.js
participant Installer
participant Badge as badge.js
participant README as README File
User->>Uninstall: npm run uninstall
Uninstall->>Installer: uninstall flow
Note over Installer: ... module removal phase ...
Installer->>Uninstall: remove modules & data
Uninstall->>Badge: findReadme(projectDir)
Badge-->>Uninstall: README file path
alt README exists
Uninstall->>README: read content
README-->>Uninstall: current content
Uninstall->>Badge: hasBadge(content)
Badge-->>Uninstall: boolean
alt Badge found
Uninstall->>Badge: removeBadge(content)
Badge-->>Uninstall: content without badge
Uninstall->>README: write updated content
README-->>Uninstall: success
else Badge not found
Uninstall-->>Uninstall: skip removal
end
else README not found
Uninstall-->>Uninstall: skip removal
end
Uninstall-->>User: uninstall complete
Estimated code review effort🎯 3 (Moderate) | ⏱️ ~25 minutes 🚥 Pre-merge checks | ✅ 4 | ❌ 1❌ Failed checks (1 warning)
✅ Passed checks (4 passed)
✏️ Tip: You can configure your own custom pre-merge checks in the settings. ✨ Finishing Touches🧪 Generate unit tests (beta)
Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out. Review rate limit: 7/8 reviews remaining, refill in 7 minutes and 30 seconds.Comment |
There was a problem hiding this comment.
Actionable comments posted: 5
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.
Inline comments:
In `@tools/installer/commands/install.js`:
- Line 99: The quick-update flow rebuilds an installConfig without carrying over
config.noBadge so badge injection still runs; update Installer.quickUpdate()
(the place that constructs installConfig) to copy/preserve config.noBadge (or
the source config field) into the new installConfig so downstream badge
injection honors the --no-badge flag; locate the installConfig construction in
quickUpdate and add the noBadge property from the incoming config object.
In `@tools/installer/commands/uninstall.js`:
- Around line 143-151: The README badge cleanup block (using badge.findReadme,
badge.hasBadge, badge.removeBadge and fs.readFile/fs.writeFile) should be
best-effort: wrap the read/write sequence in a try/catch so any fs errors are
caught and do not propagate to fail the uninstall; inside the catch log or warn
the error (e.g., via processLogger or console.warn) and continue without
rethrowing so the overall uninstall exit code remains based on the primary _bmad
removal result.
In `@tools/installer/core/badge.js`:
- Around line 6-7: BADGE_PATTERN is hardcoded to bmad-badge.vercel.app, which
breaks hasBadge() and removeBadge() when BADGE_URL is changed; update the code
to build the badge-matching RegExp from the existing BADGE_URL constant (escape
any special regex chars) instead of the hardcoded host, then use that
constructed RegExp in BADGE_PATTERN (or replace BADGE_PATTERN with a
function/getter) so hasBadge() and removeBadge() always derive their matching
logic from BADGE_URL.
- Around line 18-20: The regex in the github remote parsing (the raw.match call
that assigns httpsMatch) uses ([^/.]+) for the repo capture which strips dots;
update that regex to allow dots (e.g., use ([^/]+) for the repo group) and
ensure any trailing .git is stripped later or by matching (so
functions/variables httpsMatch and the return { owner: ..., repo: ... } will
receive the full repo name including dots).
In `@tools/installer/core/installer.js`:
- Around line 106-109: Wrap the call to
this._injectBadgeIfNeeded(paths.projectRoot, addResult) so any thrown IO errors
are caught and handled non-fatally: inside the install flow where config.noBadge
is checked, add a try/catch around the _injectBadgeIfNeeded invocation, log a
warning (including the caught error and context like paths.projectRoot and
addResult) and continue without rethrowing so the installer does not abort on
README IO failures. Ensure you still skip the call when config.noBadge is true.
🪄 Autofix (Beta)
Fix all unresolved CodeRabbit comments on this PR:
- Push a commit to this branch (recommended)
- Create a new PR with the fixes
ℹ️ Review info
⚙️ Run configuration
Configuration used: Path: .coderabbit.yaml
Review profile: CHILL
Plan: Pro
Run ID: 5ad7d03e-2829-4dbb-b88e-28c5d9640416
📒 Files selected for processing (4)
tools/installer/commands/install.jstools/installer/commands/uninstall.jstools/installer/core/badge.jstools/installer/core/installer.js
- Add badge.js module for git remote resolution, README detection, and badge injection - Integrate badge prompt into install flow with --no-badge opt-out - Support badge update when owner/repo changes on re-install - Auto-create README.md with badge if missing - Pass badge config through Config.build() for both install and quick-update paths Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
a955c86 to
4a4a7c9
Compare
|
This would irritate thousands of people. Thanks for the submission, but no, we are not doing this. |
Summary
Closes #2174
Lightweight installer integration that automatically adds a dynamic BMAD version badge to the project README during
bmad install. The badge is powered by the existing bmad-badge.vercel.app service.What it does
bmad install/bmad update, the installer detects the project's git remote (owner/repo) and injects a[ ](...)badge into the README — placed after the first heading, alongside any existing badges.bmad uninstall, the badge is automatically removed from the README.--no-badgeflag available to opt out.Files changed
tools/installer/core/badge.jstools/installer/core/installer.js_injectBadgeIfNeeded()after install, before summarytools/installer/commands/install.js--no-badgeCLI optiontools/installer/commands/uninstall.jsDesign notes
bmad-badge.vercel.app. If the BMAD team prefers to fork and deploy under an official domain, only theBADGE_URLconstant inbadge.jsneeds to change.Test plan
bmad installon a project with a git remote and README → badge appears in READMEbmad installagain → badge not duplicatedbmad install --no-badge→ no badge addedbmad uninstall→ badge removed from READMEbmad installon a project without git remote → graceful skip with warning🤖 Generated with Claude Code
via Happy